#pragma once

class ChatCommand;

class ChatCommandTable
{
	friend class CommandHandler;
	std::set<ChatCommand*> m_commands;
	ChatCommand* GetCommand(std::string cmdtext);
	void InsertCmd(void (CommandHandler::*)(std::string), std::string name, std::string helptext, ChatCommandTable* subcommands = 0);
	void InsertCmd(ChatCommand* chatcmd) { m_commands.insert(chatcmd); }
	void PrintSubcmds();
};

class ChatCommand
{
	typedef void (CommandHandler::*Callback)(std::string);
public:
	std::string InternalName;
	std::string HelpText;
	Callback ChatProc;
	ChatCommandTable* subcommands;
	void PrintHelpText();
};

class CommandHandler : public Singleton<CommandHandler>
{
	std::set<ChatCommandTable*> m_tableStore;
	ChatCommandTable* m_mainCmds;
	void HandleCommand(ChatCommand* cmg, std::string argsRemain);
public:
	CommandHandler();
	void HandleLookupAreaId(std::string args);
	void HandleInput(std::string szInput);
	void HandleSetAreaId(std::string szInput);
	void HandleCreateAreaId(std::string szInput);
	void HandleModifyAreaDbcFlags(std::string szInput);
	void HandleModifyAreaDbcZone(std::string szInput);
	void HandleModifyAreaDbcParent(std::string szInput);
};

#define sCommand (*CommandHandler::GetInstance())